package com.cloudsea.yunhaiutils.config;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.ThreadLocalRandom;

@Slf4j
@Configuration
public class SnowflakeIdConfig {
    /**
     * 数据中心ID，可根据业务需要写死或自定义
     */
    private final long datacenterId = 1;

    @Bean
    public Snowflake snowflake() {
        long workerId;
        try {
            // 1. 尝试获取本机的MAC地址，它在局域网内通常是唯一的
            byte[] mac = NetUtil.getLocalHardwareAddress();

            // 2. 将MAC地址的最后两个字节组合成一个 short 类型，然后与 31 (0x1F) 做位与运算
            // 这样可以确保 workerId 在 0-31 范围内，并且尽可能地分散
            workerId = ((mac[mac.length - 2] & 0xFF) << 8) | (mac[mac.length - 1] & 0xFF);
            workerId = workerId & 31;

            log.info("雪花算法：已成功根据 MAC 地址生成工作 ID [{}] 。", workerId);

        } catch (Exception e) {
            // 3. 如果获取MAC地址失败（例如在某些Docker容器或虚拟化环境中）
            // 则使用线程安全的随机数生成一个 0-31 之间的 workerId 作为备用方案
            workerId = ThreadLocalRandom.current().nextLong(0, 32);
            log.warn("雪花算法：获取 MAC 地址失败，使用随机 workerId [{}]。注意：在多实例部署中存在冲突风险。", workerId);
        }

        // 4. 使用计算出的 workerId 和固定的 datacenterId 创建 Snowflake 实例
        return IdUtil.getSnowflake(workerId, datacenterId);
    }
}
